home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 007a / cug317.zip / BUILDDEC.C next >
C/C++ Source or Header  |  1990-06-18  |  29KB  |  838 lines

  1. /*    $Id: builddec.c 1.2 90/06/09 18:25:13 marking Exp $
  2.  *
  3.  NAME
  4.  *    builddec.c -- build decoding tables for group 3 and group 4 images
  5.  *
  6.  TYPE
  7.  *    C source for main program and subroutines
  8.  *
  9.  SYNOPSIS
  10.  *    builddec
  11.  *
  12.  DESCRIPTION
  13.  *    This program builds tables for decoding group 3 and group 4 encoded
  14.  *    images. The tables are built as the arrays null_mode [] [],
  15.  *    null_mode_next_state [] [], horiz_mode [] [], and
  16.  *    horiz_mode_next_state [] []. The output is C source code which must
  17.  *    be compiled and linked into a decoding program.
  18.  *
  19.  RETURNS
  20.  *    zero if no errors detected, nonzero otherwise
  21.  *
  22.  LEGAL
  23.  *    Copyright 1989, 1990 Michael P. Marking, Post Office Box 8039,
  24.  *    Scottsdale, Arizona 85252-8039. All rights reserved.
  25.  *
  26.  *    License is granted by the copyright holder to distribute and use this
  27.  *    code without payment of royalties or the necessity of notification as
  28.  *    long as this notice (all the text under "LEGAL") is included.
  29.  *
  30.  *    Reference: $Id: builddec.c 1.2 90/06/09 18:25:13 marking Exp $
  31.  *
  32.  *    This program is offered without any warranty of any kind. It includes
  33.  *    no warranty of merchantability or fitness for any purpose. Testing and
  34.  *    suitability for any use are the sole responsibility of the user.
  35.  * 
  36.  HISTORY
  37.  *    $Log:    builddec.c $
  38.  * Revision 1.2  90/06/09  18:25:13  marking
  39.  * clean up comments for release
  40.  * 
  41.  * Revision 1.1  89/06/30  17:00:00  marking
  42.  * Initial revision
  43.  * 
  44.  * 
  45.  NOTES
  46.  *    1.    Since it is expected that this program will be run
  47.  *        infrequently, there is no attempt at optimization.
  48.  *    2.    The tables horiz_mode [] [] and horiz_mode_next_state [] []
  49.  *        are used in both group 3 and group 4 decoding. The tables
  50.  *        null_mode [] [] and null_mode_next_state [] [] are used only
  51.  *        in decoding group 4.
  52.  *    3.    On an XT, this can take around 15 minutes. The progress
  53.  *        messages it displays let you know it's still alive, but
  54.  *        otherwise can be ignored.
  55.  *    4.    Most of the documentation for the tables themselves is in
  56.  *        the decode routines g3tdecod.c and g4tdecod.c.
  57.  *
  58.  FILES
  59.  *    Creates the file "tables.c", which is to be compiled and linked into
  60.  *    the table-driven decoding routine.
  61.  *
  62.  PORTABILITY
  63.  *    Tested under Microsoft C 5.1. Should be fairly portable.
  64.  *
  65.  SEE ALSO
  66.  *    g3tdecod.c -- decode group 3 image using tables
  67.  *    g4tdecod.c -- decode group 4 image using tables
  68.  *    "Decoding Group 3 Images", C Users Journal, June 1990
  69.  *
  70.  INFORMATION
  71.  *    Although there is no support offered with this program, the author will
  72.  *    endeavor to correct errors. Updates will also be made available from
  73.  *    time to time.
  74.  *
  75.  *    Contact: Michael P. Marking, Post Office Box 8039, Scottsdale, Arizona
  76.  *    85252-8039 USA. Replies are not guaranteed to be swift. Beginning
  77.  *    July 1990, e-mail may be sent to uunet!ipel!marking.
  78.  *
  79.  *    Also beginning in July 1990, this code will be archived at the
  80.  *    ipel!phoenix BBS in file g3g4.zoo. The 24-hour telephone number
  81.  *    for 300/1200/2400 is (602)274-0462. When logging in, specify user
  82.  *    "public", system "bbs", and password "public".
  83.  *
  84.  *    This code is also available from the C Users Group in volume 317.
  85.  *
  86.  */
  87.  
  88. /*
  89.  *    standard headers
  90.  */
  91.  
  92. #include    <stddef.h>        /* common types and macros */
  93. #include    <stdio.h>        /* streams and files */
  94. #include    <stdlib.h>        /* assorted functions, macros, types */
  95.  
  96. /*
  97.  *    application
  98.  */
  99.  
  100. #include "g3g4.h"            /* some #defines */
  101.  
  102. #define INVALID_CODE -1
  103. #define INCOMPLETE_CODE -2
  104. #define EOL_CODE -3
  105.  
  106. unsigned long append_0 (unsigned long);
  107. unsigned long append_1 (unsigned long);
  108. short black_run_length (unsigned long);
  109. short search_run_length_table (unsigned long, long *);
  110. short white_run_length (unsigned long);
  111.  
  112. unsigned long append_0 (unsigned long prefix)
  113. {
  114.   return (prefix + 0x10000);
  115. }
  116.  
  117. unsigned long append_1 (unsigned long prefix)
  118. {
  119.   unsigned short prefix_length;
  120.   static unsigned short prefix_mask [16] = {0x8000, 0x4000, 0x2000, 0x1000,
  121.     0x0800, 0x0400, 0x0200, 0x0100, 0x0080, 0x0040, 0x0020, 0x0010, 0x0008,
  122.     0x0004, 0x0002, 0x0001};
  123.   prefix_length = 0xFF & (unsigned short) (prefix >> 16);
  124.   return (prefix + 0x10000 + prefix_mask [prefix_length]);
  125. }
  126.  
  127. short search_run_length_table (unsigned long prefix, long *p_table)
  128. {
  129.   short table_offset = 0;
  130.   long prefix_length, prefix_value;
  131.   prefix_length = 0xFF & (prefix >> 16);
  132.   prefix_value = 0xFFFF & prefix;
  133.   while (p_table [table_offset])
  134.   {
  135.     if (p_table [table_offset] == prefix_length
  136.       && p_table [table_offset + 1] == prefix_value)
  137.     return ((short) p_table [table_offset + 2]);
  138.     table_offset += 3; /* move on to next entry */
  139.   }
  140.   return (INCOMPLETE_CODE); /* no entry found in table */
  141. }
  142.  
  143. short white_run_length (unsigned long prefix)
  144. {
  145.   static long code_table [] =
  146.   {
  147.     8, 0x3500, 0, /* 0011 0101 */
  148.     6, 0x1C00, 1, /* 0001 11 */
  149.     4, 0x7000, 2, /* 0111 */
  150.     4, 0x8000, 3, /* 1000 */
  151.     4, 0xB000, 4, /* 1011 */
  152.     4, 0xC000, 5, /* 1100 */
  153.     4, 0xE000, 6, /* 1110 */
  154.     4, 0xF000, 7, /* 1111 */
  155.     5, 0x9800, 8, /* 1001 1 */
  156.     5, 0xA000, 9, /* 1010 0 */
  157.     5, 0x3800, 10, /* 0011 1 */
  158.     5, 0x4000, 11, /* 0100 0 */
  159.     6, 0x2000, 12, /* 0010 00 */
  160.     6, 0x0C00, 13, /* 0000 11 */
  161.     6, 0xD000, 14, /* 1101 00 */
  162.     6, 0xD400, 15, /* 1101 01 */
  163.     6, 0xA800, 16, /* 1010 10 */
  164.     6, 0xAC00, 17, /* 1010 11 */
  165.     7, 0x4E00, 18, /* 0100 111 */
  166.     7, 0x1800, 19, /* 0001 100 */
  167.     7, 0x1000, 20, /* 0001 000 */
  168.     7, 0x2E00, 21, /* 0010 111 */
  169.     7, 0x0600, 22, /* 0000 011 */
  170.     7, 0x0800, 23, /* 0000 100 */
  171.     7, 0x5000, 24, /* 0101 000 */
  172.     7, 0x5600, 25, /* 0101 011 */
  173.     7, 0x2600, 26, /* 0010 011 */
  174.     7, 0x4800, 27, /* 0100 100 */
  175.     7, 0x3000, 28, /* 0011 000 */
  176.     8, 0x0200, 29, /* 0000 0010 */
  177.     8, 0x0300, 30, /* 0000 0011 */
  178.     8, 0x1A00, 31, /* 0001 1010 */
  179.     8, 0x1B00, 32, /* 0001 1011 */
  180.     8, 0x1200, 33, /* 0001 0010 */
  181.     8, 0x1300, 34, /* 0001 0011 */
  182.     8, 0x1400, 35, /* 0001 0100 */
  183.     8, 0x1500, 36, /* 0001 0101 */
  184.     8, 0x1600, 37, /* 0001 0110 */
  185.     8, 0x1700, 38, /* 0001 0111 */
  186.     8, 0x2800, 39, /* 0010 1000 */
  187.     8, 0x2900, 40, /* 0010 1001 */
  188.     8, 0x2A00, 41, /* 0010 1010 */
  189.     8, 0x2B00, 42, /* 0010 1011 */
  190.     8, 0x2C00, 43, /* 0010 1100 */
  191.     8, 0x2D00, 44, /* 0010 1101 */
  192.     8, 0x0400, 45, /* 0000 0100 */
  193.     8, 0x0500, 46, /* 0000 0101 */
  194.     8, 0x0A00, 47, /* 0000 1010 */
  195.     8, 0x0B00, 48, /* 0000 1011 */
  196.     8, 0x5200, 49, /* 0101 0010 */
  197.     8, 0x5300, 50, /* 0101 0011 */
  198.     8, 0x5400, 51, /* 0101 0100 */
  199.     8, 0x5500, 52, /* 0101 0101 */
  200.     8, 0x2400, 53, /* 0010 0100 */
  201.     8, 0x2500, 54, /* 0010 0101 */
  202.     8, 0x5800, 55, /* 0101 1000 */
  203.     8, 0x5900, 56, /* 0101 1001 */
  204.     8, 0x5A00, 57, /* 0101 1010 */
  205.     8, 0x5B00, 58, /* 0101 1011 */
  206.     8, 0x4A00, 59, /* 0100 1010 */
  207.     8, 0x4B00, 60, /* 0100 1011 */
  208.     8, 0x3200, 61, /* 0011 0010 */
  209.     8, 0x3300, 62, /* 0011 0011 */
  210.     8, 0x3400, 63, /* 0011 0100 */
  211.     5, 0xD800, 64, /* 1101 1 */
  212.     5, 0x9000, 128, /* 1001 0 */
  213.     6, 0x5C00, 192, /* 0101 11 */
  214.     7, 0x6E00, 256, /* 0110 111 */
  215.     8, 0x3600, 320, /* 0011 0110 */
  216.     8, 0x3700, 384, /* 0011 0111 */
  217.     8, 0x6400, 448, /* 0110 0100 */
  218.     8, 0x6500, 512, /* 0110 0101 */
  219.     8, 0x6800, 576, /* 0110 1000 */
  220.     8, 0x6700, 640, /* 0110 0111 */
  221.     9, 0x6600, 704, /* 0110 0110 0 */
  222.     9, 0x6680, 768, /* 0110 0110 1 */
  223.     9, 0x6900, 832, /* 0110 1001 0 */
  224.     9, 0x6980, 896, /* 0110 1001 1 */
  225.     9, 0x6A00, 960, /* 0110 1010 0 */
  226.     9, 0x6A80, 1024, /* 0110 1010 1 */
  227.     9, 0x6B00, 1088, /* 0110 1011 0 */
  228.     9, 0x6B80, 1152, /* 0110 1011 1 */
  229.     9, 0x6C00, 1216, /* 0110 1100 0 */
  230.     9, 0x6C80, 1280, /* 0110 1100 1 */
  231.     9, 0x6D00, 1344, /* 0110 1101 0 */
  232.     9, 0x6D80, 1408, /* 0110 1101 1 */
  233.     9, 0x4C00, 1472, /* 0100 1100 0 */
  234.     9, 0x4C80, 1536, /* 0100 1100 1 */
  235.     9, 0x4D00, 1600, /* 0100 1101 0 */
  236.     6, 0x6000, 1664, /* 0110 00 */
  237.     9, 0x4D80, 1728, /* 0100 1101 1 */
  238.     11, 0x0100, 1792, /* 0000 0001 000 */
  239.     11, 0x0180, 1856, /* 0000 0001 100 */
  240.     11, 0x01A0, 1920, /* 0000 0001 101 */
  241.     12, 0x0120, 1984, /* 0000 0001 0010 */
  242.     12, 0x0130, 2048, /* 0000 0001 0011 */
  243.     12, 0x0140, 2112, /* 0000 0001 0100 */
  244.     12, 0x0150, 2176, /* 0000 0001 0101 */
  245.     12, 0x0160, 2240, /* 0000 0001 0110 */
  246.     12, 0x0170, 2304, /* 0000 0001 0111 */
  247.     12, 0x01C0, 2368, /* 0000 0001 1100 */
  248.     12, 0x01D0, 2432, /* 0000 0001 1101 */
  249.     12, 0x01E0, 2496, /* 0000 0001 1110 */
  250.     12, 0x01F0, 2560, /* 0000 0001 1111 */
  251.     12, 0x0010, EOL_CODE, /* 0000 0000 0001 */
  252.     9, 0x0080, INVALID_CODE, /* 0000 0000 1 */
  253.     10, 0x0040, INVALID_CODE, /* 0000 0000 01 */
  254.     11, 0x0020, INVALID_CODE, /* 0000 0000 001 */
  255.     12, 0x0000, INVALID_CODE, /* 0000 0000 0000 */
  256.     0 /* end-of-table */
  257.   };
  258.   return (search_run_length_table (prefix, code_table));
  259. }
  260.    
  261. short black_run_length (unsigned long prefix)
  262. {
  263.   static long code_table [] =
  264.   {
  265.     10, 0x0DC0, 0, /* 0000 1101 11 */
  266.     3, 0x4000, 1, /* 010 */
  267.     2, 0xC000, 2, /* 11 */
  268.     2, 0x8000, 3, /* 10 */
  269.     3, 0x6000, 4, /* 011 */
  270.     4, 0x3000, 5, /* 0011 */
  271.     4, 0x2000, 6, /* 0010 */
  272.     5, 0x1800, 7, /* 0001 1 */
  273.     6, 0x1400, 8, /* 0001 01 */
  274.     6, 0x1000, 9, /* 0001 00 */
  275.     7, 0x0800, 10, /* 0000 100 */
  276.     7, 0x0A00, 11, /* 0000 101 */
  277.     7, 0x0E00, 12, /* 0000 111 */
  278.     8, 0x0400, 13, /* 0000 0100 */
  279.     8, 0x0700, 14, /* 0000 0111 */
  280.     9, 0x0C00, 15, /* 0000 1100 0 */
  281.     10, 0x05C0, 16, /* 0000 0101 11 */
  282.     10, 0x0600, 17, /* 0000 0110 00 */
  283.     10, 0x0200, 18, /* 0000 0010 00 */
  284.     11, 0x0CE0, 19, /* 0000 1100 111 */
  285.     11, 0x0D00, 20, /* 0000 1101 000 */
  286.     11, 0x0D80, 21, /* 0000 1101 100 */
  287.     11, 0x06E0, 22, /* 0000 0110 111 */
  288.     11, 0x0500, 23, /* 0000 0101 000 */
  289.     11, 0x02E0, 24, /* 0000 0010 111 */
  290.     11, 0x0300, 25, /* 0000 0011 000 */
  291.     12, 0x0CA0, 26, /* 0000 1100 1010 */
  292.     12, 0x0CB0, 27, /* 0000 1100 1011 */
  293.     12, 0x0CC0, 28, /* 0000 1100 1100 */
  294.     12, 0x0CD0, 29, /* 0000 1100 1101 */
  295.     12, 0x0680, 30, /* 0000 0110 1000 */
  296.     12, 0x0690, 31, /* 0000 0110 1001 */
  297.     12, 0x06A0, 32, /* 0000 0110 1010 */
  298.     12, 0x06B0, 33, /* 0000 0110 1011 */
  299.     12, 0x0D20, 34, /* 0000 1101 0010 */
  300.     12, 0x0D30, 35, /* 0000 1101 0011 */
  301.     12, 0x0D40, 36, /* 0000 1101 0100 */
  302.     12, 0x0D50, 37, /* 0000 1101 0101 */
  303.     12, 0x0D60, 38, /* 0000 1101 0110 */
  304.     12, 0x0D70, 39, /* 0000 1101 0111 */
  305.     12, 0x06C0, 40, /* 0000 0110 1100 */
  306.     12, 0x06D0, 41, /* 0000 0110 1101 */
  307.     12, 0x0DA0, 42, /* 0000 1101 1010 */
  308.     12, 0x0DB0, 43, /* 0000 1101 1011 */
  309.     12, 0x0540, 44, /* 0000 0101 0100 */
  310.     12, 0x0550, 45, /* 0000 0101 0101 */
  311.     12, 0x0560, 46, /* 0000 0101 0110 */
  312.     12, 0x0570, 47, /* 0000 0101 0111 */
  313.     12, 0x0640, 48, /* 0000 0110 0100 */
  314.     12, 0x0650, 49, /* 0000 0110 0101 */
  315.     12, 0x0520, 50, /* 0000 0101 0010 */
  316.     12, 0x0530, 51, /* 0000 0101 0011 */
  317.     12, 0x0240, 52, /* 0000 0010 0100 */
  318.     12, 0x0370, 53, /* 0000 0011 0111 */
  319.     12, 0x0380, 54, /* 0000 0011 1000 */
  320.     12, 0x0270, 55, /* 0000 0010 0111 */
  321.     12, 0x0280, 56, /* 0000 0010 1000 */
  322.     12, 0x0580, 57, /* 0000 0101 1000 */
  323.     12, 0x0590, 58, /* 0000 0101 1001 */
  324.     12, 0x02B0, 59, /* 0000 0010 1011 */
  325.     12, 0x02C0, 60, /* 0000 0010 1100 */
  326.     12, 0x05A0, 61, /* 0000 0101 1010 */
  327.     12, 0x0660, 62, /* 0000 0110 0110 */
  328.     12, 0x0670, 63, /* 0000 0110 0111 */
  329.     10, 0x03C0, 64, /* 0000 0011 11 */
  330.     12, 0x0C80, 128, /* 0000 1100 1000 */
  331.     12, 0x0C90, 192, /* 0000 1100 1001 */
  332.     12, 0x05B0, 256, /* 0000 0101 1011 */
  333.     12, 0x0330, 320, /* 0000 0011 0011 */
  334.     12, 0x0340, 384, /* 0000 0011 0100 */
  335.     12, 0x0350, 448, /* 0000 0011 0101 */
  336.     13, 0x0360, 512, /* 0000 0011 0110 0 */
  337.     13, 0x0368, 576, /* 0000 0011 0110 1 */
  338.     13, 0x0250, 640, /* 0000 0010 0101 0 */
  339.     13, 0x0258, 704, /* 0000 0010 0101 1 */
  340.     13, 0x0260, 768, /* 0000 0010 0110 0 */
  341.     13, 0x0268, 832, /* 0000 0010 0110 1 */
  342.     13, 0x0390, 896, /* 0000 0011 1001 0 */
  343.     13, 0x0398, 960, /* 0000 0011 1001 1 */
  344.     13, 0x03A0, 1024, /* 0000 0011 1010 0 */
  345.     13, 0x03A8, 1088, /* 0000 0011 1010 1 */
  346.     13, 0x03B0, 1152, /* 0000 0011 1011 0 */
  347.     13, 0x03B8, 1216, /* 0000 0011 1011 1 */
  348.     13, 0x0290, 1280, /* 0000 0010 1001 0 */
  349.     13, 0x0298, 1344, /* 0000 0010 1001 1 */
  350.     13, 0x02A0, 1408, /* 0000 0010 1010 0 */
  351.     13, 0x02A8, 1472, /* 0000 0010 1010 1 */
  352.     13, 0x02D0, 1536, /* 0000 0010 1101 0 */
  353.     13, 0x02D8, 1600, /* 0000 0010 1101 1 */
  354.     13, 0x0320, 1664, /* 0000 0011 0010 0 */
  355.     13, 0x0328, 1728, /* 0000 0011 0010 1 */
  356.     11, 0x0100, 1792, /* 0000 0001 000 */
  357.     11, 0x0180, 1856, /* 0000 0001 100 */
  358.     11, 0x01A0, 1920, /* 0000 0001 101 */
  359.     12, 0x0120, 1984, /* 0000 0001 0010 */
  360.     12, 0x0130, 2048, /* 0000 0001 0011 */
  361.     12, 0x0140, 2112, /* 0000 0001 0100 */
  362.     12, 0x0150, 2176, /* 0000 0001 0101 */
  363.     12, 0x0160, 2240, /* 0000 0001 0110 */
  364.     12, 0x0170, 2304, /* 0000 0001 0111 */
  365.     12, 0x01C0, 2368, /* 0000 0001 1100 */
  366.     12, 0x01D0, 2432, /* 0000 0001 1101 */
  367.     12, 0x01E0, 2496, /* 0000 0001 1110 */
  368.     12, 0x01F0, 2560, /* 0000 0001 1111 */
  369.     12, 0x0010, EOL_CODE, /* 0000 0000 0001 */
  370.     9, 0x0080, INVALID_CODE, /* 0000 0000 1 */
  371.     10, 0x0040, INVALID_CODE, /* 0000 0000 01 */
  372.     11, 0x0020, INVALID_CODE, /* 0000 0000 001 */
  373.     12, 0x0000, INVALID_CODE, /* 0000 0000 0000 */
  374.     0 /* end-of-table */
  375.   };
  376.   return (search_run_length_table (prefix, code_table));
  377. }
  378.  
  379. #define NULL_MODE_PREFIX_LIMIT 200 /* maximum number of null-mode prefixes */
  380. #define HORIZ_MODE_PREFIX_LIMIT 250 /* maximum number of indigestible
  381.   1-dimensional prefixes */
  382.  
  383. long null_mode_prefix [NULL_MODE_PREFIX_LIMIT];
  384.   /* the bit string corresponding to this row of the decoding table */
  385. unsigned char null_mode [NULL_MODE_PREFIX_LIMIT] [256];
  386.   /* one of the entries PASS_MODE, HORIZONTAL_MODE, etc, or zero */
  387. unsigned char null_mode_next_state [NULL_MODE_PREFIX_LIMIT] [256];
  388.   /* next row of the decoding tables to be used */
  389. short null_mode_prefix_count = 0;
  390.   /* number of prefixes or rows in the G4 decoding tables */
  391.  
  392. /* decoding script values for horiz_mode [] []:
  393.      0 - indigestible code
  394.      1 - invalid code or error
  395.      2..105 - white runs
  396.      106..209 - black runs
  397.      210 - EOL (valid only for Group 3)
  398.      211..255 - (undefined) */
  399. unsigned char horiz_mode [HORIZ_MODE_PREFIX_LIMIT] [256];
  400. unsigned char horiz_mode_next_state [HORIZ_MODE_PREFIX_LIMIT] [256];
  401.   /* if the corresponding horiz_mode [] [] entry is zero ("indigestible"),
  402.      this entry is a row number for decoding the next byte; otherwise, it
  403.      is the bit number to continue coding the next codeword */
  404. long horiz_mode_prefix [HORIZ_MODE_PREFIX_LIMIT];
  405.   /* the prefixes corresponding to the rows of the decoding table */
  406. char horiz_mode_color [HORIZ_MODE_PREFIX_LIMIT];
  407.   /* color of next run, BLACK or WHITE */
  408. short horiz_mode_prefix_count = 0;
  409.  
  410. static unsigned char bit_mask [8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04,
  411.   0x02, 0x01};
  412.  
  413. void build_null_mode_tables (void);
  414. short find_horiz_mode_prefix (long, char);
  415. short find_null_mode_prefix (long);
  416. short null_mode_type (long);
  417. void process_horiz_mode_prefixes (void);
  418. short horiz_mode_code_black (short);
  419. short horiz_mode_code_invalid (void);
  420. short horiz_mode_code_indigestible (void);
  421. short horiz_mode_code_EOL (void);
  422. short horiz_mode_code_white (short);
  423. void write_tables (void);
  424.  
  425. int main (int arg_count, char **p_args, char **p_env)
  426. {
  427.   printf ("g4build\n");
  428.   /* build the null mode decoding tables */
  429.     build_null_mode_tables ();
  430.     printf ("  %hd null mode prefixes defined\n", null_mode_prefix_count);
  431.   /* build the 1D decoding tables */
  432.     printf ("  building 1D scripts...\n");
  433.     process_horiz_mode_prefixes ();
  434.     printf ("  %hd indigestible prefixes defined\n", horiz_mode_prefix_count);
  435.   /* create tables.h */
  436.     write_tables ();
  437.   exit (0);
  438. }
  439.  
  440. void build_null_mode_tables ()
  441. {
  442.   short prefix_number;
  443.   /* note: the first eight entries correspond to a null prefix and starting
  444.     bit numbers 0, 1, ... 7 */
  445.   null_mode_prefix_count = 8;
  446.   for (prefix_number = 0; prefix_number < null_mode_prefix_count;
  447.    prefix_number++)
  448.   {
  449.     short byte_value;
  450.     for (byte_value = 0; byte_value < 256; byte_value++)
  451.     {
  452.       short beginning_bit_number, bit_number, mode;
  453.       long working_prefix;
  454.       char found_code = 0;
  455.       if (prefix_number < 8)
  456.       {
  457.         working_prefix = 0L;
  458.         beginning_bit_number = prefix_number;
  459.       }
  460.       else
  461.       {
  462.         working_prefix = null_mode_prefix [prefix_number];
  463.         beginning_bit_number = 0;
  464.       }
  465.       for (bit_number = beginning_bit_number; bit_number < 8 && !found_code;
  466.        bit_number++)
  467.       {
  468.         if (bit_mask [bit_number] & byte_value)
  469.       working_prefix = append_1 (working_prefix);
  470.     else working_prefix = append_0 (working_prefix);
  471.         mode = null_mode_type (working_prefix);
  472.         switch (mode)
  473.         {
  474.       case PASS_MODE:
  475.       case HORIZONTAL_MODE:
  476.       case VERTICAL_V0_MODE:
  477.       case VERTICAL_VR1_MODE:
  478.       case VERTICAL_VR2_MODE:
  479.       case VERTICAL_VR3_MODE:
  480.       case VERTICAL_VL1_MODE:
  481.       case VERTICAL_VL2_MODE:
  482.       case VERTICAL_VL3_MODE:
  483.       case EXT_MODE_UNCOMPRESSED:
  484.       case ERROR_MODE:
  485.       case ERROR_MODE_1:
  486.         found_code = 1;
  487.         null_mode [prefix_number] [byte_value] = (unsigned char) mode;
  488.         null_mode_next_state [prefix_number] [byte_value]
  489.           = (unsigned char) ((bit_number + 1) & 0x7);
  490.           /* note: if the bit number is 8, then
  491.             the table entry will be zero, which indicates a new byte
  492.             is to be fetched during the decoding process */
  493.         break;
  494.       default:
  495.         break;
  496.         }
  497.       }
  498.       if (!found_code)
  499.       {
  500.     null_mode_next_state [prefix_number] [byte_value]
  501.       = (unsigned char) find_null_mode_prefix (working_prefix);
  502.     null_mode [prefix_number] [byte_value] = 0; /* indicating to the
  503.       decoder that no digestible state was found */
  504.       }
  505.     }
  506.   }
  507. }
  508.  
  509. short find_null_mode_prefix (long prefix)
  510. {
  511.   short j1;
  512.   if (prefix == 0L) return (0);
  513.   for (j1 = 8; j1 < null_mode_prefix_count; j1++)
  514.     if (prefix == null_mode_prefix [j1]) return (j1);
  515.   if (null_mode_prefix_count == NULL_MODE_PREFIX_LIMIT)
  516.   {
  517.     printf ("ERROR: null mode prefix table overflow\n");
  518.     exit (1);
  519.   }
  520.   null_mode_prefix [null_mode_prefix_count] = prefix;
  521. printf ("adding null mode prefix [%hd] 0x%lx\n", null_mode_prefix_count,
  522. prefix);
  523.   null_mode_prefix_count++;
  524.   return (null_mode_prefix_count - 1);
  525. }
  526.  
  527. short find_horiz_mode_prefix (long prefix, char color)
  528. {
  529.   short j1;
  530.   for (j1 = 0; j1 < horiz_mode_prefix_count; j1++)
  531.     if (prefix == horiz_mode_prefix [j1] && horiz_mode_color [j1] == color)
  532.       return (j1);
  533.   /* it wasn't found, so add it to the tables */
  534.   /* but first, is there room? */
  535.     if (horiz_mode_prefix_count == HORIZ_MODE_PREFIX_LIMIT) /* we're full */
  536.     {
  537.       printf ("ERROR: 1D prefix table overflow\n");
  538.       exit (1);
  539.     }
  540.   /* OK, there's room... */
  541.   horiz_mode_prefix [horiz_mode_prefix_count] = prefix;
  542.   horiz_mode_color [horiz_mode_prefix_count] = color;
  543.   horiz_mode_prefix_count++;
  544. printf ("\n horiz mode prefix %hd, color %c = 0x%lx ",
  545. (short) (horiz_mode_prefix_count - 1), "WB" [color], prefix);
  546.   return (horiz_mode_prefix_count - 1);
  547. }
  548.  
  549. short null_mode_type (long prefix)
  550. {
  551.   if (prefix == 0x18000L) return (VERTICAL_V0_MODE);      /* 1 */
  552.   if (prefix == 0x36000L) return (VERTICAL_VR1_MODE);     /* 011 */
  553.   if (prefix == 0x34000L) return (VERTICAL_VL1_MODE);     /* 010 */
  554.   if (prefix == 0x32000L) return (HORIZONTAL_MODE);       /* 001 */
  555.   if (prefix == 0x41000L) return (PASS_MODE);             /* 0001 */
  556.   if (prefix == 0x60C00L) return (VERTICAL_VR2_MODE);     /* 0000 11 */
  557.   if (prefix == 0x60800L) return (VERTICAL_VL2_MODE);     /* 0000 10 */
  558.   if (prefix == 0x70600L) return (VERTICAL_VR3_MODE);     /* 0000 011 */
  559.   if (prefix == 0x70400L) return (VERTICAL_VL3_MODE);     /* 0000 010 */
  560.   if (prefix == 0x80200L) return (ERROR_MODE);            /* 0000 0010 */
  561.   if (prefix == 0x90300L) return (ERROR_MODE);            /* 0000 0011 0 */
  562.   if (prefix == 0xA0380L) return (ERROR_MODE);            /* 0000 0011 10 */
  563.   if (prefix == 0xA03C0L) return (EXT_MODE_UNCOMPRESSED); /* 0000 0011 11 */
  564.   if (prefix == 0x70000L) return (ERROR_MODE_1);          /* 0000 000 */
  565.     /* under the assumption that there are no errors in the file, then this
  566.        bit string can only be the beginning of an EOFB (end-of-facsimile-block)
  567.        code */
  568.   return (-1);
  569. }
  570.  
  571. void process_horiz_mode_prefixes ()
  572. {
  573.   unsigned short code_byte_value;
  574.   short prefix_number;
  575.   horiz_mode_prefix_count = 16; /* the first 8 are for white, the second 8 are
  576.     for black, beginning with bits 0, 1, ... 7 */
  577.   for (prefix_number = 0; prefix_number < horiz_mode_prefix_count;
  578.     prefix_number++)
  579.     for (code_byte_value = 0; code_byte_value < 256; code_byte_value++)
  580.     {
  581.       short bits_digested = 0;
  582.       short bit_number, beginning_bit_number;
  583.       char working_color;
  584.       long working_prefix;
  585.       if (prefix_number < 8)
  586.       {
  587.     working_color = WHITE;
  588.     working_prefix = 0L;
  589.     beginning_bit_number = prefix_number;
  590.       }
  591.       else if (prefix_number < 16)
  592.       {
  593.     working_color = BLACK;
  594.     working_prefix = 0L;
  595.     beginning_bit_number = prefix_number - 8;
  596.       }
  597.       else
  598.       {
  599.         working_color = horiz_mode_color [prefix_number];
  600.         working_prefix = horiz_mode_prefix [prefix_number];
  601.     beginning_bit_number = 0;
  602.       }
  603.       for (bit_number = beginning_bit_number; bit_number < 8 && !bits_digested;
  604.     bit_number++)
  605.       {
  606.     if (bit_mask [bit_number] & code_byte_value)
  607.       working_prefix = append_1 (working_prefix);
  608.     else working_prefix = append_0 (working_prefix);
  609.     if (working_prefix == 0xC0000L) working_prefix = 0xB0000L;
  610.       /* This conversion allows for arbitrary strings of zeroes to precede
  611.          the end-of-line code 0000 0000 0001.  It assumes no errors in the
  612.          data, and is based on the assumption that the code replaced (12
  613.          consecutive zeroes) can only be "legally" encountered before the
  614.          end-of-line code.  This assumption is valid only for a Group 3
  615.          image; the combination will never occur in horizontal mode in a
  616.          proper Group 4 image. */
  617.     if (working_color == WHITE)
  618.     {
  619.       short runlength;
  620.       runlength = white_run_length (working_prefix);
  621.       if (runlength == INVALID_CODE)
  622.       {
  623.         horiz_mode [prefix_number] [code_byte_value]
  624.           = (unsigned char) horiz_mode_code_invalid ();
  625.         horiz_mode_next_state [prefix_number] [code_byte_value]
  626.           = (unsigned char) bit_number;
  627.         bits_digested = bit_number + 1;
  628.       }
  629.       else if (runlength == EOL_CODE) /* Group 3 only */
  630.       {
  631.         horiz_mode [prefix_number] [code_byte_value]
  632.           = (unsigned char) horiz_mode_code_EOL ();
  633.         horiz_mode_next_state [prefix_number] [code_byte_value]
  634.           = (unsigned char) ((bit_number + 1) & 0x7);
  635.         bits_digested = bit_number + 1;
  636.       }
  637.       else if (runlength != INCOMPLETE_CODE)
  638.       {
  639.         horiz_mode [prefix_number] [code_byte_value]
  640.           = (unsigned char) horiz_mode_code_white (runlength);
  641.         horiz_mode_next_state [prefix_number] [code_byte_value]
  642.           = (unsigned char) ((bit_number + 1) & 0x7);
  643.         bits_digested = bit_number + 1;
  644.       }
  645.       /* else incomplete code */
  646.     }
  647.     else /* working_color == BLACK */
  648.     {
  649.       short runlength;
  650.       runlength = black_run_length (working_prefix);
  651.       if (runlength == INVALID_CODE)
  652.       {
  653.         horiz_mode [prefix_number] [code_byte_value]
  654.           = (unsigned char) horiz_mode_code_invalid ();
  655.         horiz_mode_next_state [prefix_number] [code_byte_value]
  656.           = (unsigned char) (bit_number + 8);
  657.         bits_digested = bit_number + 1;
  658.       }
  659.       else if (runlength == EOL_CODE) /* Group 3 only */
  660.       {
  661.         horiz_mode [prefix_number] [code_byte_value]
  662.           = (unsigned char) horiz_mode_code_EOL ();
  663.         horiz_mode_next_state [prefix_number] [code_byte_value]
  664.           = (unsigned char) ((bit_number + 1) & 0x7);
  665.         bits_digested = bit_number + 1;
  666.       }
  667.       else if (runlength != INCOMPLETE_CODE)
  668.       {
  669.         horiz_mode [prefix_number] [code_byte_value]
  670.           = (unsigned char) horiz_mode_code_black (runlength);
  671.         horiz_mode_next_state [prefix_number] [code_byte_value]
  672.           = (unsigned char) ((bit_number + 1) & 0x7);
  673.         bits_digested = bit_number + 1;
  674.       }
  675.       /* else incomplete code */
  676.     }
  677.       }
  678.       if (!bits_digested) /* if no codewords after examining byte */
  679.       {
  680.     horiz_mode [prefix_number] [code_byte_value]
  681.       = (unsigned char) horiz_mode_code_indigestible ();
  682.     horiz_mode_next_state [prefix_number] [code_byte_value]
  683.       = (unsigned char) find_horiz_mode_prefix (working_prefix,
  684.         working_color);
  685.       }
  686.     }
  687. }
  688.  
  689. short horiz_mode_code_black (short runlength)
  690. {
  691.   /*
  692.     0    106
  693.     1    107
  694.     ...    ...
  695.     63    169
  696.     64    170
  697.     128    171
  698.     ...    ...
  699.     2560    209
  700.   */
  701.   if (runlength < 64) return (runlength + 106);
  702.   else return ((runlength / 64) + 169);
  703. }
  704.  
  705. short horiz_mode_code_invalid ()
  706. {
  707.   return (1);
  708. }
  709.  
  710. short horiz_mode_code_indigestible ()
  711. {
  712.   return (0);
  713. }
  714.  
  715. short horiz_mode_code_EOL ()
  716. {
  717.   return (210);
  718. }
  719.  
  720. short horiz_mode_code_white (short runlength)
  721. {
  722.   /*
  723.     0    2
  724.     1    3
  725.     ...    ...
  726.     63    65
  727.     64    66
  728.     128    67
  729.     ...    ...
  730.     2560    105
  731.   */
  732.   if (runlength < 64) return (runlength + 2);
  733.   else return ((runlength / 64) + 65);
  734. }
  735.  
  736. void write_tables ()
  737. {
  738.   FILE *p_table_file;
  739.   short j1, j2, j3;
  740.   p_table_file = fopen ("tables.c", "w+");
  741.   if (p_table_file == NULL)
  742.   {
  743.     printf ("can't open \"tables.c\"\n");
  744.     exit (1);
  745.   }
  746.   /* ---------------------------------------- null_mode [] [] */
  747.   fprintf (p_table_file,
  748.     "unsigned char null_mode [%hd] [256] = {\n",
  749.     null_mode_prefix_count);
  750.   for (j1 = 0; j1 < null_mode_prefix_count; j1++)
  751.   {
  752.     fprintf (p_table_file, "/* %hd */", j1);
  753.     j3 = 1;
  754.     fprintf (p_table_file, "  { ");
  755.     for (j2 = 0; j2 < 256; j2++)
  756.     {
  757.       fprintf (p_table_file, "%hd", (short) null_mode [j1] [j2]);
  758.       if (j3++ == 14)
  759.       {
  760.     j3 = 0; fprintf (p_table_file, ",\n    ");
  761.       }
  762.       else if (j2 != 255) fprintf (p_table_file, ", ");
  763.     }
  764.     if (j1 == horiz_mode_prefix_count - 1) fprintf (p_table_file, "  }\n");
  765.     else fprintf (p_table_file, "  },\n");
  766.   }
  767.   fprintf (p_table_file, "};\n");
  768.   /* ---------------------------------------- null_mode_next_state [] [] */
  769.   fprintf (p_table_file,
  770.     "unsigned char null_mode_next_state [%hd] [256] = {\n",
  771.     null_mode_prefix_count);
  772.   for (j1 = 0; j1 < null_mode_prefix_count; j1++)
  773.   {
  774.     fprintf (p_table_file, "/* %hd */", j1);
  775.     j3 = 1;
  776.     fprintf (p_table_file, "  { ");
  777.     for (j2 = 0; j2 < 256; j2++)
  778.     {
  779.       fprintf (p_table_file, "%hd", (short) null_mode_next_state [j1] [j2]);
  780.       if (j3++ == 14)
  781.       {
  782.     j3 = 0; fprintf (p_table_file, ",\n    ");
  783.       }
  784.       else if (j2 != 255) fprintf (p_table_file, ", ");
  785.     }
  786.     if (j1 == horiz_mode_prefix_count - 1) fprintf (p_table_file, "  }\n");
  787.     else fprintf (p_table_file, "  },\n");
  788.   }
  789.   fprintf (p_table_file, "};\n");
  790.   /* ---------------------------------------- horiz_mode [] [] */
  791.   fprintf (p_table_file,
  792.     "unsigned char horiz_mode [%hd] [256] = {\n",
  793.     horiz_mode_prefix_count);
  794.   for (j1 = 0; j1 < horiz_mode_prefix_count; j1++)
  795.   {
  796.     j3 = 1;
  797.     fprintf (p_table_file, "/* %hd */", j1);
  798.     fprintf (p_table_file, "  { ");
  799.     for (j2 = 0; j2 < 256; j2++)
  800.     {
  801.       fprintf (p_table_file, "%hd", (short) horiz_mode [j1] [j2]);
  802.       if (j3++ == 11)
  803.       {
  804.     j3 = 0; fprintf (p_table_file, ",\n    ");
  805.       }
  806.       else if (j2 != 255) fprintf (p_table_file, ", ");
  807.     }
  808.     if (j1 == horiz_mode_prefix_count - 1) fprintf (p_table_file, "  }\n");
  809.     else fprintf (p_table_file, "  },\n");
  810.   }
  811.   fprintf (p_table_file, "};\n");
  812.   /* ---------------------------------------- horiz_mode_next_state [] [] */
  813.   fprintf (p_table_file,
  814.     "unsigned char horiz_mode_next_state [%hd] [256] = {\n",
  815.     horiz_mode_prefix_count);
  816.   for (j1 = 0; j1 < horiz_mode_prefix_count; j1++)
  817.   {
  818.     fprintf (p_table_file, "/* %hd */", j1);
  819.     j3 = 1;
  820.     fprintf (p_table_file, "  { ");
  821.     for (j2 = 0; j2 < 256; j2++)
  822.     {
  823.       fprintf (p_table_file, "%hd", (short) horiz_mode_next_state [j1] [j2]);
  824.       if (j3++ == 14)
  825.       {
  826.     j3 = 0; fprintf (p_table_file, ",\n    ");
  827.       }
  828.       else if (j2 != 255) fprintf (p_table_file, ", ");
  829.     }
  830.     if (j1 == horiz_mode_prefix_count - 1) fprintf (p_table_file, "  }\n");
  831.     else fprintf (p_table_file, "  },\n");
  832.   }
  833.   fprintf (p_table_file, "};\n");
  834.   fclose (p_table_file);
  835. }
  836.  
  837. /*    end $RCSfile: builddec.c $ */
  838.